package com.palmgo.utils.drawer.basic;



import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import javafx.scene.Scene;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.palmgo.utils.drawer.model.ConvertFactors;
import com.palmgo.utils.drawer.model.DataType;
import com.palmgo.utils.drawer.model.DrawInfo;
import com.palmgo.utils.drawer.model.LatLng;
import com.palmgo.utils.drawer.model.RectF;
import com.palmgo.utils.drawer.model.RoadType;
import com.palmgo.utils.drawer.model.Segment;
import com.palmgo.utils.drawer.model.TrafficSegment;
import com.palmgo.utils.drawer.model.Vetrux;
import com.palmgo.utils.drawer.model.ZipUtils;

/**
 * 掌城道路路况绘制工具
 *
 * @author tanqiyong
 */
public class DeformationAgientOld {
	private static Logger LOG = LoggerFactory.getLogger(DeformationAgientOld.class);
    /**
     * 图像的边距
     */
    private final int ROAD_GRAPHIC_INTERVAL_DEF = 40;
    /**
     * 额定总绘图区域
     */
    private final int ROAD_GRAPHIC_WIDTH_DEF = 560;
   
    private final int PADDING = 40;
    /**
     * 道路的宽度
     */
    private int ROAD_GRAPHIC_LINE_WIDTH = 30;
    /**
     * 图像的边距
     */
    private float ROAD_GRAPHIC_INTERVAL = 40;
    /**
     * 额定总绘图区域
     */
    private float ROAD_GRAPHIC_WIDTH = 560;
    /**
     * 额定中心图像区域
     */
    private float ROAD_GRAPHIC_WIDTH_NOINTERVAL = ROAD_GRAPHIC_WIDTH
            - ROAD_GRAPHIC_INTERVAL * 2;
    private static float FONTSIZE_DEF = 24;
    private String unZipdata;
    private byte[] zipdata;

    private Segment segment;
    //双向整条路
    private List<Segment> froadList;
    private List<Segment> rroadList;

    private DataType type = DataType.JSON;
    private int width;
    private int height;
    private float fontSize = 18;
    private int roadWidth = 40;
    private List<LatLng> locations;
    private double direction;
    private boolean bottomCenter = false;
    private RoadType roadType = RoadType.DOUBLE;
    /** 变量:TODO,类型:GraphicsContext */
    GraphicsContext context;
    /** 变量:背景颜色,类型:Color */
    private Color backColor = Color.color(35d / 256, 37d / 256, 55d / 256);
    /** 变量:图片名称,类型:String */
    private String pngName;
    
    public DeformationAgientOld() {
    }

    public void setData(String unZipdata) {
        this.unZipdata = unZipdata;
    }

    public void setData(byte[] zipdata) {
        this.zipdata = zipdata;
    }

    public void setData(Segment segment) {
        this.segment = segment;
    }

    /**
	 * 设置属性backColor的值，参数类型Color
	 * @param backColor the backColor to set
	 */
	public void setBackColor(Color backColor) {
		this.backColor = backColor;
	}

	public void setData(List<Segment> froadList, List<Segment> rroadList) {
        this.froadList = froadList;
        this.rroadList = rroadList;
    }

    public void setDataType(DataType type) {
        this.type = type;
    }

    public void setFontSize(float fontSize) {
        this.fontSize = fontSize;
    }

    public void setRoadWidth(int roadWidth) {
        this.roadWidth = roadWidth;
    }

    public void setLocations(List<LatLng> locations) {
        this.locations = locations;
    }

    public void setDirection(double direction) {
        this.direction = direction;
    }

    public void setNeedBottomCenter(boolean bottomCenter) {
        this.bottomCenter = bottomCenter;
    }

    public void setRoadType(RoadType roadType) {
        this.roadType = roadType;
    }
    
//
//    public WritableImage convert() {
//        try {
//            width = bitmap.getWidth();
//            height = bitmap.getHeight();
//            if (width <= 0 || height <= 0) {
//                // 图片不正确，无法绘制
//                return bitmap;
//            }
//            //判断数据类型
//            if (zipdata != null) {
//                drawByZipdata();
//            } else if (!TextUtils.isEmpty(unZipdata)) {
//                drawByUnZipdata();
//            } else if (segment != null) {
//                drawByPath();
//            } else if (froadList != null && rroadList != null) {
//                drawByAllRoad();
//            }
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return bitmap;
//    }

    /**
	 * 获取属性 pngName的值
	 * @return the pngName : String
	 */
	public String getPngName() {
		return pngName;
	}

	/**
	 * 设置属性pngName的值，参数类型String
	 * @param pngName the pngName to set
	 */
	public void setPngName(String pngName) {
		this.pngName = pngName;
	}

	public WritableImage convert(Scene scene,GraphicsContext gc) {
        try {
            width = (int)scene.getWidth();
            height = (int)scene.getHeight();
            if (width <= 0 || height <= 0) {
                // 图片不正确，无法绘制
                return null;
            }
            context = gc;
            context.clearRect(0, 0, scene.getWidth(),scene.getHeight());
            context.setFill(backColor);
            context.fillRect(0, 0,scene.getWidth(),scene.getHeight());
            context.beginPath();
            //判断数据类型
            if (zipdata != null) {
                drawByZipdata();
            } else if (!isEmpty(unZipdata)) {
                drawByUnZipdata();
            } else if (segment != null) {
                drawByPath();
            } else if (froadList != null && rroadList != null) {
                drawByAllRoad();
            }
            return scene.snapshot(null);
        } catch (Exception e) {
        	LOG.error("绘制单张图片异常,pngName="+getPngName(),e);
            return null;
        }
       
    }
    void drawByZipdata() {
        try {
            String data = "";
            if (zipdata != null) {
                data = ZipUtils.unZip(zipdata);
            }
            if (isEmpty(data))
                return;
            if (roadType == RoadType.SINGLE) {
                createFrontRoadBmp(data);
            } else {
                createRoadBmp(data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void drawByUnZipdata() {
        if (isEmpty(unZipdata))
            return;
        if (roadType == RoadType.SINGLE) {
            createFrontRoadBmp(unZipdata);
        } else {
            createRoadBmp(unZipdata);
        }
    }

    void drawByPath() {
        createPathOfLineBmp(segment, 0);
    }

    void drawByAllRoad() {
        createAllOfLineBmp(froadList, rroadList, 0);
    }

    protected static class LocationPoint {
        LatLng location;
        double minDis1;
        int index1;
        double minDis2;
        int index2;

        public LocationPoint(LatLng location) {
            this.location = location;
        }
    }

    private void createFrontRoadBmp(String data) {
//        try {
//            List<GraphicTrafficEntity> datas = JSON2BeanUtils.comperJson2List(
//                    new JSONArray(data), GraphicTrafficEntity.class);
//            for (GraphicTrafficEntity b : datas) {
//                String[] coord = b.coord.split(",");
//                double lat = Double.valueOf(coord[1]);
//                double lng = Double.valueOf(coord[0]);
//                b.pt = new LatLng(lat, lng);
//                if (b.froadBean != null) {
//                    b.froadBean.traffic_status = formatTrafficStatus(b.froadBean.traffic_status);
//                }
//                if (b.rroadBean != null) {
//                    b.rroadBean.traffic_status = formatTrafficStatus(b.rroadBean.traffic_status);
//                }
//            }
//            boolean isRroadDirction = true;
//            // 计算所有需要绘制的点
//            // 记录下距离最近的点
//            if (locations != null && locations.size() > 0) {
//                // 获取所有距离最近的两个点，用以确定一条线
//                LatLng curLL = locations.get(0);
//                LocationPoint p = new LocationPoint(curLL);
//                // 找出它到每个点的距离，
//                for (int j = 0; j < datas.size(); j++) {
//                    LatLng l1 = datas.get(j).pt;
//                    double dLat = curLL.latitude - l1.latitude;
//                    double dLng = curLL.longitude - l1.longitude;
//                    double dis = Math.sqrt(dLat * dLat + dLng * dLng);
//                    if (j == 0) {
//                        p.minDis1 = dis;
//                        p.index1 = j;
//                    } else if (j == 1) {
//                        p.minDis2 = dis;
//                        p.index2 = j;
//                    } else if (dis < p.minDis1 || dis < p.minDis2) {
//                        if (p.minDis1 < p.minDis2) {
//                            p.minDis2 = dis;
//                            p.index2 = j;
//                        } else {
//                            p.minDis1 = dis;
//                            p.index1 = j;
//                        }
//
//                    }
//                }
//                // 计算到道路起点的距离，如果越来越远，则是正向
//                LatLng fll = locations.get(0);
//                LatLng ell = locations.get(locations.size() - 1);
//                LatLng lineStartLL = datas.get(0).pt;
//                double llat1 = fll.latitude - lineStartLL.latitude;
//                double llong1 = fll.longitude - lineStartLL.longitude;
//                double disL = Math.sqrt(llat1 * llat1 + llong1 * llong1);
//                double llat2 = ell.latitude - lineStartLL.latitude;
//                double llong2 = ell.longitude - lineStartLL.longitude;
//                double disF = Math.sqrt(llat2 * llat2 + llong2 * llong2);
//                if (disF <= disL) {
//                    // 远离的方向，更新远的点
//                    int pos = Math.min(p.index1, p.index2);
//                    datas.get(pos).pt = locations.get(0);
//                    datas = datas.subList(pos, datas.size());
//                } else {
//                    int pos = Math.max(p.index1, p.index2);
//                    datas.get(pos).pt = locations.get(0);
//                    if (pos + 1 < datas.size()) {
//                        pos++;
//                    }
//                    datas = datas.subList(0, pos);
//                    isRroadDirction = false;
//                }
//            } else {
//                // 数据不够时，需要用方向判断isRroadDirction
//                LatLng sp = datas.get(0).pt;
//                LatLng ep = datas.get(datas.size() - 1).pt;
//                double roadDegrees = Math.toDegrees(Math.atan2(ep.latitude
//                        - sp.latitude, ep.longitude - sp.longitude));
//                double carDegrees = 90 - roadDegrees;// 因为行车方向正北为0，坐标轴正东为0
//                if (Math.abs(carDegrees - direction) <= 90) {
//                    isRroadDirction = true;
//                } else {
//                    isRroadDirction = false;
//                }
//            }
//            // 计算角度
//            if (locations != null && locations.size() > 1) {
//                LatLng firstOne = locations.get(locations.size() - 1);
//                LatLng lastOne = locations.get(0);
//                double dy = lastOne.latitude - firstOne.latitude;
//                double dx = lastOne.longitude - firstOne.longitude;
//                direction = Math.toDegrees(Math.atan2(dy, dx));
//                if (dx < 0) {
//                    direction = -270 - direction;
//                } else {
//                    direction = 90 - direction;
//                }
//            }
//
//            // 将数据组装成需要的格式
//            List<Segment> rroad = new ArrayList<Segment>();
//            Segment item;
//            for (int i = 0; i < datas.size() - 1; i++) {
//                GraphicTrafficEntity curObj = datas.get(i);
//                GraphicTrafficEntity nextObj = datas.get(i + 1);
//                if (curObj.rroadBean == null) {
//                    // 获取最后一个数据，将节点放入队尾,如果没有节点，不处理数据
//                    if (rroad.size() > 0) {
//                        item = rroad.get(rroad.size());
//                        item.pts.add(curObj.pt);
//                        if (nextObj.rroadBean != null) {
//                            item.endname = curObj.segmentname;
//                            item.pts.add(nextObj.pt);
//                        }
//                    }
//                } else {
//                    // curObj.rroadBean != null,将新元素加入队列中
//                    item = new Segment();
//                    item.pts.add(curObj.pt);
//                    item.startname = curObj.segmentname;
//                    item.trafficlistBeans.add(curObj.rroadBean);
//                    // 如果两个连续，直接结束当前元素
//                    if (nextObj.rroadBean != null) {
//                        item.endname = nextObj.segmentname;
//                        item.pts.add(nextObj.pt);
//                    }
//                    if (i == datas.size() - 2) {
//                        item.endname = nextObj.segmentname;
//                        item.pts.add(nextObj.pt);
//                    }
//                    rroad.add(item);
//                }
//            }
//            List<Segment> froad = new ArrayList<Segment>();
//            for (int i = datas.size() - 1; i > 0; i--) {
//                GraphicTrafficEntity curObj = datas.get(i);
//                GraphicTrafficEntity nextObj = datas.get(i - 1);
//                if (curObj.froadBean == null) {
//                    // 获取最后一个数据，将节点放入队尾,如果没有节点，不处理数据
//                    if (froad.size() > 0) {
//                        item = froad.get(froad.size());
//                        item.pts.add(curObj.pt);
//                        if (nextObj.froadBean != null) {
//                            item.endname = curObj.segmentname;
//                            item.pts.add(nextObj.pt);
//                        }
//                    }
//                } else {
//                    // curObj.froadBean != null,将新元素加入队列中
//                    item = new Segment();
//                    item.pts.add(curObj.pt);
//                    item.startname = curObj.segmentname;
//                    item.trafficlistBeans.add(curObj.froadBean);
//                    // 如果两个连续，直接结束当前元素
//                    if (nextObj.froadBean != null) {
//                        item.endname = nextObj.segmentname;
//                        item.pts.add(nextObj.pt);
//                    }
//                    if (i == 1) {
//                        item.endname = nextObj.segmentname;
//                        item.pts.add(nextObj.pt);
//                    }
//                    froad.add(item);
//                }
//            }
//            // 2.解析数据
//            return createDefineLineBmp(isRroadDirction ? rroad : froad);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    private String formatTrafficStatus(String status) {
        try {
            if (status.contains("畅")) {
                return "C";
            } else if (status.contains("缓")) {
                return "B";
            } else if (status.contains("堵")) {
                return "A";
            }
        } catch (Exception e) {
        }
        return "N";
    }

    /**
     * 生成双向行驶的道路路况，数据来源于道路，如：北四环
     *
     * @return
     */
    private void createRoadBmp(String data) {
//        try {
//            List<GraphicTrafficEntity> datas = JSON2BeanUtils.comperJson2List(
//                    new JSONArray(data), GraphicTrafficEntity.class);
//            for (GraphicTrafficEntity b : datas) {
//                String[] coord = b.coord.split(",");
//                int lat = (int) (Double.valueOf(coord[1]) * 1e6);
//                int lng = (int) (Double.valueOf(coord[0]) * 1e6);
//                b.pt = new LatLng(lat, lng);
//                if (b.froadBean != null) {
//                    b.froadBean.traffic_status = formatTrafficStatus(b.froadBean.traffic_status);
//                }
//                if (b.rroadBean != null) {
//                    b.rroadBean.traffic_status = formatTrafficStatus(b.rroadBean.traffic_status);
//                }
//            }
//            // 将数据组装成需要的格式
//            List<Segment> rroad = new ArrayList<Segment>();
//            List<Segment> froad = new ArrayList<Segment>();
//            Segment item;
//            int size = datas.size();
//            for (int i = 0; i < size; i++) {
//                GraphicTrafficEntity curObj = datas.get(i);
//                if (curObj.rroadBean != null) {
//                    item = new Segment();
//                    item.pts.add(curObj.pt);
//                    if (rroad.isEmpty())
//                        item.startname = curObj.segmentname;
//                    else
//                        item.endname = curObj.segmentname;
//                    item.trafficlistBeans.add(curObj.rroadBean);
//                    rroad.add(item);
//                }
//                if (curObj.froadBean != null) {
//                    item = new Segment();
//                    item.pts.add(curObj.pt);
//                    if (froad.isEmpty())
//                        item.startname = curObj.segmentname;
//                    else
//                        item.endname = curObj.segmentname;
//                    item.trafficlistBeans.add(curObj.froadBean);
//                    froad.add(item);
//                }
//            }
//            // 2.解析数据
//            return createAllOfLineBmp(froad, rroad, 0);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }
    /**
     * 绘制整条路段 <br>
     * 耗时计算，建议开启异步线程
     *
     * @param froad 正向路况数据
     * @return
     */
    protected void createPathOfLineBmp(Segment froad, double routeAngle) {
        try {
            if (roadWidth > 0) {
                ROAD_GRAPHIC_LINE_WIDTH = roadWidth;
            }
            initScale(width, height);
            List<Vetrux> m_vectors1 = new ArrayList<Vetrux>();
            List<TrafficSegment> m_traffic_segments1 = new ArrayList<TrafficSegment>();
            ConvertFactors factors = new ConvertFactors();
            /** 正向 */
            DrawInfo drawinfo = new DrawInfo();
            // 解析折线编码
            DecodeUtils.decodePoly(segment.coords, segment.pts);
            makingShowArea(segment.pts, factors);
            for (Segment.Traffic traffic : segment.trafficlistBeans) {
                drawinfo.arrRoadCondition.add(traffic.traffic_status);
            }
            // 计算坐标转换因子
            calcCoordinateFactorByCity(factors, width, height);
            // 转化坐标，并得到绘制点信息
            DrawInfo.Flag flag = new DrawInfo.Flag(true);
                getConvertCoordsByCity(segment, drawinfo, factors, flag);
            // 计算旋转角
            calcRouteByCity(drawinfo, width, height, routeAngle);
            // ==========END=======基础数据处理完成
            //生成segment
            addTrafficSegement(drawinfo, m_vectors1,
                    m_traffic_segments1, true);
            //去重，将数据封入segment
            rebuild_traffic_segment(
                    m_traffic_segments1,
                    TrafficGraphic.segment_outline_type_e.down_segment_outline);
            //生成绘制道路所用数据
            List<Line> lines1 = new ArrayList<Line>(m_vectors1.size() - 1);
            calcRouteParams(m_vectors1, m_traffic_segments1, ROAD_GRAPHIC_LINE_WIDTH / 2, lines1);
            // 绘制路段路况
            TrafficGraphic.draw_traffic_flow(context, m_traffic_segments1);
            if (fontSize <= 0) {
                fontSize = FONTSIZE_DEF;
            }
            List<RectF> textRects = new ArrayList<RectF>();
            List<TextParam> textParams1 = new ArrayList<TextParam>();
            List<TextParam> textParams2 = new ArrayList<TextParam>();
            calcTextFlowParams(m_traffic_segments1, lines1, textParams1);
            //文字去重
            rebuildTextFlowParams(textParams1, textParams2);
            draw_text_flow(context, textParams1, textRects, m_vectors1, m_traffic_segments1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 绘制整条路段 <br>
     * 耗时计算，建议开启异步线程
     *
     * @param froad 正向路况数据
     * @param rroad 反向路况数据
     * @return
     */
    protected void createAllOfLineBmp(List<Segment> froad,
                                        List<Segment> rroad, double routeAngle) {
        try {
            if (roadWidth > 0) {
                ROAD_GRAPHIC_LINE_WIDTH = roadWidth;
            }
            initScale(width, height);
            List<Vetrux> m_vectors1 = new ArrayList<Vetrux>();
            List<TrafficSegment> m_traffic_segments1 = new ArrayList<TrafficSegment>();
            List<Vetrux> m_vectors2 = new ArrayList<Vetrux>();
            List<TrafficSegment> m_traffic_segments2 = new ArrayList<TrafficSegment>();
            ConvertFactors factors = new ConvertFactors();
            /** 正向 */
            DrawInfo positiveDrawInfo = new DrawInfo();
            // /** 反向 */
            DrawInfo reverseDrawInfo = new DrawInfo();
            // 解析折线编码
            getRoadConditionByCity(froad, positiveDrawInfo, factors);
            getRoadConditionByCity(rroad, reverseDrawInfo, factors);
            // 计算坐标转换因子
            calcCoordinateFactorByCity(factors, width, height);
            // 转化坐标，并得到绘制点信息
            getConvertCoordsByCity(froad, positiveDrawInfo, factors);
            getConvertCoordsByCity(rroad, reverseDrawInfo, factors);
            // 计算旋转角
            calcRouteByCity(positiveDrawInfo, width, height, routeAngle);
            calcRouteByCity(reverseDrawInfo, width, height, routeAngle);
            // ==========END=======基础数据处理完成
            //生成segment
            addTrafficSegement(positiveDrawInfo, m_vectors1,
                    m_traffic_segments1, true);
            addTrafficSegement(reverseDrawInfo, m_vectors2,
                    m_traffic_segments2, false);
            //去重，将数据封入segment
            rebuild_traffic_segment(
                    m_traffic_segments1,
                    TrafficGraphic.segment_outline_type_e.down_segment_outline);
            //生成绘制道路所用数据
            List<Line> lines1 = new ArrayList<Line>(m_vectors1.size() - 1);
            List<Line> lines2 = new ArrayList<Line>(m_vectors1.size() - 1);
            calcRouteParams(m_vectors1, m_traffic_segments1, ROAD_GRAPHIC_LINE_WIDTH / 2, lines1);
            rebuild_traffic_segment(
                    m_traffic_segments2,
                    TrafficGraphic.segment_outline_type_e.down_segment_outline);
            calcRouteParams(m_vectors2, m_traffic_segments2, ROAD_GRAPHIC_LINE_WIDTH / 2, lines2);
            // 绘制路段路况
            TrafficGraphic.draw_traffic_flow(context, m_traffic_segments1);
            TrafficGraphic.draw_traffic_flow(context, m_traffic_segments2);
            if (fontSize <= 0) {
                fontSize = FONTSIZE_DEF;
            }

            List<RectF> textRects = new ArrayList<RectF>();
            List<TextParam> textParams1 = new ArrayList<TextParam>();
            List<TextParam> textParams2 = new ArrayList<TextParam>();
            calcTextFlowParams(m_traffic_segments1, lines1, textParams1);
            calcTextFlowParams(m_traffic_segments2, lines2, textParams2);
            //文字去重
            rebuildTextFlowParams(textParams1, textParams2);
            List<TrafficSegment> segments = new ArrayList<TrafficSegment>(m_traffic_segments1.size() + m_traffic_segments2.size());
            segments.addAll(m_traffic_segments1);
            segments.addAll(m_traffic_segments2);
            draw_text_flow(context, textParams1, textRects, m_vectors1, segments);
            draw_text_flow(context, textParams2, textRects, m_vectors2, segments);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void rebuildTextFlowParams(List<TextParam> textParams1, List<TextParam> textParams2) {
        int len1 = textParams1.size();
        int mark = 0;//如果使用i，i会因为i--而一直是同一列，计算结果有问题
        for (int i = 0; i < len1; i++) {
            String text1 = textParams1.get(i).text;
            for (TextParam p : textParams2) {
                if (p.text.equals(text1)) {
                    if (mark % 2 == 0)
                        textParams2.remove(p);
                    else {
                        textParams1.remove(i);
                        i--;
                        len1--;
                    }
                    mark++;
                    break;
                }
            }
        }
    }

    private class TextParam {
        String text;
        Vetrux pt;
        Line line;

        protected TextParam(String text,
                            Vetrux vetrux,
                            Line line) {
            this.text = text;
            this.pt = vetrux;
            this.line = line;
        }
    }

    void calcTextFlowParams(List<TrafficSegment> segments, List<Line> lines, List<TextParam> texts) {
        if (segments == null || segments.isEmpty()) return;
        int segLen = segments.size();
        for (int i = 0; i < segLen; i++) {
            TrafficSegment s = segments.get(i);
            if (i == 0 && !isEmpty(s.startText)) {
                texts.add(new TextParam(s.startText, s.downOutLine.get(0), lines.get(0)));
            }
            if (!isEmpty(s.endText)) {
            	try{
            		texts.add(new TextParam(s.endText, s.downOutLine.get(s.downOutLine.size() / 2 - 1), lines.get(s.vertex_count - 1)));
            	}catch(Exception e){
            		LOG.error("渲染时计算文字参数异常,fileName="+getPngName());
            	}
            }
        }
    }

    void draw_text_flow(GraphicsContext context, List<TextParam> textParams, List<RectF> textRects, List<Vetrux> m_vectors1, List<TrafficSegment> segments) {
        int segLen = textParams.size();
        int cursor = 0;
        Vetrux sp = m_vectors1.get(0);
        Vetrux ep = m_vectors1.get(m_vectors1.size() - 1);
        double degress = Math.toDegrees(Math.atan2(ep.y - sp.y, ep.x - sp.x));
        TextDriction roadDriction = getTextDriction(degress);
        RectF box = new RectF(0, 0, width, height);
        for (TextParam param : textParams) {
            drawText(context, param.text, param.pt, param.line, roadDriction, box, textRects, segments, fontSize);
        }
    }

    /**
     * 判断区域是否越界
     *
     * @param box
     * @param r
     * @return
     */
    private boolean isIncludeBox(RectF box, RectF r) {
        return box.left <= r.left && box.top <= r.top && box.right >= r.right && box.bottom >= r.bottom;
    }

    /**
     * 判断文字区域是否和现有区域相交
     *
     * @param rs
     * @param r
     * @return
     */
    private boolean interSect(List<RectF> rs, RectF r) {
        for (RectF r1 : rs) {
            double maxLeft = Math.max(r1.left, r.left);
            double maxTop = Math.max(r1.top, r.top);
            double minRight = Math.min(r1.right, r.right);
            double minBottom = Math.min(r1.bottom, r.bottom);
            if (maxLeft < minRight && maxTop < minBottom)
                return true;
        }
        return false;
    }

    private boolean interSect(RectF r1, RectF r) {
        double maxLeft = Math.max(r1.left, r.left);
        double maxTop = Math.max(r1.top, r.top);
        double minRight = Math.min(r1.right, r.right);
        double minBottom = Math.min(r1.bottom, r.bottom);
        return maxLeft < minRight && maxTop < minBottom;
    }

    private void drawText(GraphicsContext context, String text, Vetrux pt, Line l, TextDriction textDriction, RectF area, List<RectF> textRects, List<TrafficSegment> segments, float fontSize) {
        //1.计算路段与X轴夹角
        //2.获取文字的绘制方向
//        TextDriction driction = textDriction;
        TextDriction driction = getTextDriction(l.degress);
        //3.获取文字区域
        RectF textRect = getTextRect(text, pt, fontSize, driction, 0.6f * roadWidth);
        //验证区域是否与现有区域重叠
        if (!isIncludeBox(area, textRect) || interSect(textRects, textRect) || interRoad(segments, textRect)) {
            //验证另一方向
            driction = getOtherTextDriction(driction);
            textRect = getTextRect(text, pt, fontSize, driction, 0.6f * roadWidth);
            if (!isIncludeBox(area, textRect) || interSect(textRects, textRect) || interRoad(segments, textRect))
                return;
        }
        context.setFont(Font.font("黑体", fontSize));
        context.setFill(Color.WHITE);
        //如果文字垂直走向，需要每行绘制一个字
        if (driction == TextDriction.TOP_BOTTOM || driction == TextDriction.BOTTOM_TOP) {
            int strLen = text.length();
            double textHeight = textRect.height() / strLen;
            for (int j = 0; j < strLen; j++) {
                String str = text.substring(j, j + 1);
                context.fillText(str, textRect.left, textRect.top + (j + 1) * textHeight);
            }
        } else {
        	context.fillText(text, textRect.left, textRect.bottom);
        }
        //绘制文字标记
        drawTextFlag(context, pt, roadWidth * 0.3f, driction);
        textRects.add(textRect);
    }

    private boolean interRoad(List<TrafficSegment> segments, RectF textRect) {
        for (TrafficSegment segment : segments) {
            Vetrux p1 = segment.downOutLine.get(0);
            Vetrux p2 = segment.downOutLine.get(segment.downOutLine.size() / 2);
            RectF r = new RectF(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));
            if (interSect(textRect, r))
                return true;
        }
        return false;
    }

    private void drawTextFlag(GraphicsContext context, Vetrux pt, float roadWidth, TextDriction driction) {
    	context.beginPath();
    	switch (driction) {
            case TOP_BOTTOM:
            	context.moveTo(pt.x, pt.y + roadWidth / 2);
            	context.lineTo(pt.x - roadWidth / 2, pt.y + roadWidth * 3 / 2);
                context.lineTo(pt.x + roadWidth / 2, pt.y + roadWidth * 3 / 2);
                break;
            case BOTTOM_TOP:
            	context.moveTo(pt.x, pt.y - roadWidth / 2);
            	context.lineTo(pt.x - roadWidth / 2, pt.y - roadWidth * 3 / 2);
            	context.lineTo(pt.x + roadWidth / 2, pt.y - roadWidth * 3 / 2);
                break;
            case LEFT_RIGHT:
            	context.moveTo(pt.x + roadWidth / 2, pt.y);
            	context.lineTo(pt.x + roadWidth * 3 / 2, pt.y - roadWidth / 2);
            	context.lineTo(pt.x + roadWidth * 3 / 2, pt.y + roadWidth / 2);
                break;
            case RIGHT_LEFT:
            	context.moveTo(pt.x - roadWidth / 2, pt.y);
            	context.lineTo(pt.x - roadWidth * 3 / 2, pt.y - roadWidth / 2);
            	context.lineTo(pt.x - roadWidth * 3 / 2, pt.y + roadWidth / 2);
                break;
            default:
                break;
        }
        context.closePath();
        context.setStroke(Color.WHITE);
        context.stroke();
    }


    private RectF getTextRect(String text, Vetrux pt, float width, TextDriction driction, float offSet) {
        RectF result = new RectF();
        switch (driction) {
            case TOP_BOTTOM:
                result.set(pt.x - width / 2, pt.y + offSet, pt.x + width / 2, pt.y + offSet + (width + 4) * text.length());
                break;
            case BOTTOM_TOP:
                result.set(pt.x - width / 2, pt.y - offSet - (width + 4) * text.length(), pt.x + width/ 2, pt.y - offSet);
                break;
            case LEFT_RIGHT:
                result.set(pt.x + offSet, pt.y - width / 2, pt.x + offSet + (width + 4) * text.length(), pt.y + width/ 2);
                break;
            case RIGHT_LEFT:
                result.set(pt.x - offSet - (width + 4) * text.length(), pt.y - width / 2, pt.x - offSet, pt.y + width / 2);
                break;
            default:
                break;
        }
        return result;
    }

    /**
     * 获取文字的绘制方向
     *
     * @param degress
     * @return
     */
    TextDriction getTextDriction(double degress) {
        if (degress >= -45 && degress <= 45) {
            return TextDriction.TOP_BOTTOM;
        } else if ((degress >= -180 && degress <= -135) || (degress >= 135 && degress <= 180)) {
            return TextDriction.BOTTOM_TOP;
        } else if (degress > 45 && degress < 135) {
            return TextDriction.RIGHT_LEFT;
        } else if (degress > -135 && degress < -45) {
            return TextDriction.LEFT_RIGHT;
        }
        return TextDriction.LEFT_RIGHT;
    }

    /**
     * 获取另一可显示方向
     *
     * @param driction
     * @return
     */
    TextDriction getOtherTextDriction(TextDriction driction) {
        switch (driction) {
            case LEFT_RIGHT:
                return TextDriction.TOP_BOTTOM;
            case TOP_BOTTOM:
                return TextDriction.LEFT_RIGHT;
            case BOTTOM_TOP:
                return TextDriction.RIGHT_LEFT;
            default:
                return TextDriction.BOTTOM_TOP;
        }
    }

    enum TextDriction {
        TOP_BOTTOM, BOTTOM_TOP, RIGHT_LEFT, LEFT_RIGHT
    }
    void remoteVectx(List<Vetrux> vectors1,List<TrafficSegment> segments){
    	int delElems = 0;
    	int start = 0;
    	int end =0;
    	for (TrafficSegment seg:segments) {
			end = seg.vertex_count -delElems;
			for (int i = start; i < end; i++) {
				Vetrux p0 = vectors1.get(i);
				Vetrux p1 = vectors1.get(i+1);
				if (p0.x==p1.x && p0.y==p1.y) {
					delElems++;
					vectors1.remove(i+1);
					i--;
					end--;
				}
			}
			seg.vertex_count -= delElems;
			//将下一节点的起点设置为此节点的终点
			start = seg.vertex_count;
		}
    }
    void calcRouteParams(List<Vetrux> m_vectors1,
                         List<TrafficSegment> segments, int roadWidth, List<Line> lines) {
        if (m_vectors1 == null || m_vectors1.isEmpty()) return;
        remoteVectx(m_vectors1, segments);
        int len = m_vectors1.size();
        List<Vetrux> vectors2 = new ArrayList<Vetrux>(len + 1);
        //计算出拓宽的vectors
        //firstpt
        Vetrux lastPt = m_vectors1.get(0);
        Vetrux curPt = m_vectors1.get(1);
        Vetrux firstPt = calcRouteXPoint(lastPt, curPt, roadWidth, true);
        //endpt
        lastPt = m_vectors1.get(len - 2);
        curPt = m_vectors1.get(len - 1);
        Vetrux endPt = calcRouteXPoint(lastPt, curPt, roadWidth, false);
        //calc lines
        for (int i = 0; i < len - 1; i++) {
        	Vetrux last = m_vectors1.get(i);
        	Vetrux cur = m_vectors1.get(i + 1);
            lines.add(calcRouteDrig(last, cur, roadWidth));
        }
        //add vectors
        //add first
        vectors2.add(firstPt);
        //add others
        //calc 交点lines.size = vCount-1
        for (int i = 0; i < len - 2; i++) {
            Line l1 = lines.get(i);
            Line l2 = lines.get(i + 1);
            double sx = 0, sy = 0;
            if (!Double.isNaN(l1.a) && !Double.isNaN(l2.a)) {
                if (l1.degress == l2.degress) {
                    //与X平行，取原来的点的x作为x
                    sx = m_vectors1.get(i+1).x;
                    sy = l1.a * sx + l1.b;
                } else {
                    sx = (l2.b - l1.b) / (l1.a - l2.a);
                    //y=ax+b
                    sy = l1.a * sx + l1.b;
                }
            } else if (Double.isNaN(l1.a) && !Double.isNaN(l2.a)) {
                //x=b => sx=l1.b
                sx = l1.b;
                sy = l2.a * sx + l2.b;
            } else if (!Double.isNaN(l1.a) && Double.isNaN(l2.a)) {
                //x=b => sx=l2.b
                sx = l2.b;
                sy = l1.a * sx + l1.b;
            } else if (Double.isNaN(l1.a) && Double.isNaN(l2.a)) {
                //与Y轴平行的两行线，没有交点，所以交点就是原点平移，lo是v0,v1的线，所以l(i)与l(i+1)的线  交点是v(i+1)
                sx = l1.b;
                sy = m_vectors1.get(i + 1).y;
            }
            vectors2.add(new Vetrux((int) sx, (int) sy));
        }
        //add end
        vectors2.add(endPt);
        //get endVector
        vectors2.add(getEndVector(endPt, m_vectors1.get(len - 1), lines.get(lines.size() - 1), roadWidth));
        /******calc end**********/
        int cursor = 0;
        for (TrafficSegment segment : segments) {
            int vCount = segment.vertex_count - cursor + 1;
            //如果节点没有两个纬度无法绘图
            if (vCount < 2) continue;
            segment.downOutLine.clear();
            for (int i = cursor; i <= segment.vertex_count; i++) {
                segment.downOutLine.add(vectors2.get(i));
            }
            //判断是否为最后一项
            if (segment.vertex_count == m_vectors1.size() - 1)
                segment.downOutLine.add(vectors2.get(len));
            for (int i = segment.vertex_count; i >= cursor; i--) {
                segment.downOutLine.add(m_vectors1.get(i));
            }
            cursor = segment.vertex_count;
            //end
        }
    }

    private Vetrux getEndVector(Vetrux endPt, Vetrux endPt1, Line line, int roadWidth) {
        //移动坐标y=ax，x2+y2=roadwidth2=> ax*ax+x*x=roadWidth*roadWidth=>x=Math.sqre(roadWidth*roadWidth/(a*a+1))
        Point p = new Point();
        if (line.a == null) {
            //x=b
            p.setLocation(endPt.x, endPt.y + roadWidth * (line.degress > 0 ? 1 : -1));
        } else {
            //以endPt为原点，直线则为y=ax
            double degress = Math.toDegrees(Math.atan2(endPt1.y - endPt.y, endPt1.x - endPt.x));
            TextDriction driction = getTextDriction(line.degress);
            double s = degress <= 0 ? 1 : -1;
            double x = Math.sqrt(roadWidth * roadWidth / (line.a * line.a + 1)) * s;
            //基于endPt重新获得坐标值
            p.setLocation((float) (endPt.x + x), (float) (endPt.y + line.a * x));
        }
        //根据endPt1获取最终点
        return new Vetrux((endPt1.x + p.x) / 2, (endPt1.y + p.y) / 2);
    }

    // y=ax+b;
    private static class Line {
        Double a;
        //b=y-ax;
        double b;
        double degress;
    }

    Vetrux calcRouteXPoint(Vetrux perviousPt, Vetrux curPt, double roadWidth, boolean first) {
        double detalY = curPt.y - perviousPt.y;
        double detalX = curPt.x - perviousPt.x;
        double dis = Math.sqrt(detalY * detalY + detalX * detalX);
        double x;
        double y;
        if (first) {
            x = perviousPt.x - detalY / dis * roadWidth;
            y = perviousPt.y + detalX / dis * roadWidth;
        } else {
            x = curPt.x - detalY / dis * roadWidth;
            y = curPt.y + detalX / dis * roadWidth;
        }
        //perviousPt在平行线上的垂点
        Vetrux firstPt = new Vetrux((int) x, (int) y);
        return firstPt;
    }

    Line calcRouteDrig(Vetrux perviousPt, Vetrux curPt, double roadWidth) {
        double detalY = curPt.y - perviousPt.y;
        double detalX = curPt.x - perviousPt.x;
        double dis = Math.sqrt(detalY * detalY + detalX * detalX);
        double x = perviousPt.x - detalY / dis * roadWidth;
        double y = perviousPt.y + detalX / dis * roadWidth;
        //perviousPt在平行线上的垂点
        Point firstPt = new Point((int) x, (int) y);
        Line line = new Line();
        line.degress = Math.toDegrees(Math.atan2(detalY, detalX));
        //如果degress==90度，x=b
        if (detalX == 0) {
            line.a = Double.NaN;
            if (detalY==0) 
            	line.b = perviousPt.x-roadWidth;
            	else
            line.b = firstPt.x;
        } else {
            //y=ax+b
            line.a = detalY / detalX;
            line.b = firstPt.y - line.a * firstPt.x;
        }
//        System.err.println(perviousPt.toString());System.err.println(curPt.toString());
//        System.err.println(detalX+"////"+line.a+","+line.b);
        return line;
    }

    /**
     * 计算旋转角
     *
     * @param positiveDrawInfo
     */
    private void calcRouteByCity(DrawInfo positiveDrawInfo, int width,
                                 int height, double routeAngle) {
        try {
            Point center = new Point(width / 2, height / 2);
            for (DrawInfo.DrawInfoUnit item : positiveDrawInfo.arrDrawInfo) {
                double dx = item.x - center.x;
                double dy = center.y - item.y;
                double dis = Math.sqrt(dx * dx + dy * dy);// 点到中心点的半径
                double oldAngle = Math.toDegrees(Math.atan2(dy, dx));
                double angle = oldAngle + routeAngle;
                double fx = center.x + dis * Math.cos(Math.toRadians(angle));
                double fy = center.y - dis * Math.sin(Math.toRadians(angle));
                item.x = fx;
                item.y = fy;
            }
        } catch (Exception e) {
        }
    }

    /**
     * 绘制路径规划路段 <br>
     * 耗时计算，建议开启异步线程
     *
     * @return
     */
    protected void createDefineLineBmp(List<Segment> segments) {
        try {
            ROAD_GRAPHIC_LINE_WIDTH = roadWidth;
            if (segments == null) {
                return ;
            }
            initScale(width, height);
            List<Vetrux> m_vectors1 = new ArrayList<Vetrux>();
            List<TrafficSegment> m_traffic_segments1 = new ArrayList<TrafficSegment>();
            ConvertFactors factors = new ConvertFactors();
            /** 正向 */
            DrawInfo positiveDrawInfo = new DrawInfo();
            /** 反向 */
            getRoadConditionByCity(segments, positiveDrawInfo, factors);
            // 重新计算经纬度范围
            calcGraphictpBottomCenter(factors, locations, bottomCenter);
            // 计算坐标转换因子
            calcCoordinateFactorByCity(factors, width, height);
            // 转化坐标，并得到绘制点信息
            getConvertCoordsByCity(segments, positiveDrawInfo, factors);
            // 计算旋转角
            calcRouteByCity(positiveDrawInfo, width, height, direction);
            // Y轴平移图像
            calcGraphicLocation(width, height, positiveDrawInfo, bottomCenter);
            // ==========END=======基础数据处理完成
            // 绘制数据开始
            TrafficGraphic.segment_end_type_e se_type;
            addTrafficSegement(positiveDrawInfo, m_vectors1,
                    m_traffic_segments1, true);
            //
            se_type = TrafficGraphic.segment_end_type_e.triangle_end_t;
            rebuild_traffic_segment(m_traffic_segments1,
                    TrafficGraphic.segment_outline_type_e.down_segment_outline);
            TrafficGraphic.calc_traffic_segment_outline(m_vectors1,
                    m_traffic_segments1,
                    TrafficGraphic.segment_outline_type_e.down_segment_outline,
                    ROAD_GRAPHIC_LINE_WIDTH, se_type);
            // 制作image
            // 绘制路段路况
            TrafficGraphic.draw_traffic_flow(context, m_traffic_segments1);
            RectF rbox = new RectF(0, 0, ROAD_GRAPHIC_WIDTH, ROAD_GRAPHIC_WIDTH);
            if (fontSize <= 0) {
                fontSize = FONTSIZE_DEF;
            }
            if (m_traffic_segments1.size() > 0) {
                TrafficGraphic.draw_traffic_text(context, m_vectors1,
                        m_traffic_segments1, rbox, ROAD_GRAPHIC_LINE_WIDTH,
                        fontSize);
            }
//            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 沿Y轴平移图片，使其底部居中
     *
     * @param width
     * @param height
     * @param positiveDrawInfo
     * @param bottomCenter
     */
    private void calcGraphicLocation(int width, int height,
                                     DrawInfo positiveDrawInfo, boolean bottomCenter) {
        if (!bottomCenter) {
            return;
        }
        try {
            // 获取纵坐标需要平移的量
            List<DrawInfo.DrawInfoUnit> infos = positiveDrawInfo.arrDrawInfo;
            double y1 = infos.get(0).y;
            double y2 = infos.get(infos.size() - 1).y;
            double y = Math.max(y1, y2);
            double distance = height - PADDING - y;
            for (DrawInfo.DrawInfoUnit unit : infos) {
                unit.y += distance;
            }
        } catch (Exception e) {
        }
    }

    /**
     * 图片底部居中
     *
     * @param factors
     * @param locations
     */
    private void calcGraphictpBottomCenter(ConvertFactors factors,
                                           List<LatLng> locations, boolean bottomCenter) {
        try {
            if (!bottomCenter || locations == null || locations.size() == 0) {
                return;
            }
            // DOTO
            LatLng curPt = locations.get(0);
            double centerLng = (factors.maxLongitude + factors.minLongitude) / 2;
            if (centerLng < curPt.longitude) {
                factors.maxLongitude = 2 * curPt.longitude
                        - factors.minLongitude;
            } else if (centerLng > curPt.longitude) {
                factors.minLongitude = 2 * curPt.longitude
                        - factors.maxLongitude;
            }
        } catch (Exception e) {
        }
    }

    /**
     * 解析折线编码
     *
     * @param segments
     * @param drawinfo
     */
    void getRoadConditionByCity(List<Segment> segments, DrawInfo drawinfo,
                                ConvertFactors factors) {
        
    	try {
            for (Segment segment : segments) {
            	if(segment.coords!=null){
            		DecodeUtils.decodePoly(segment.coords, segment.pts);
            	}
                makingShowArea(segment.pts, factors);
                for (Segment.Traffic traffic : segment.trafficlistBeans) {
                    drawinfo.arrRoadCondition.add(traffic.traffic_status);
                }
            }
        } catch (Exception e) {
        	LOG.error("解析折线编码异常,msg="+e.getLocalizedMessage());
        }
    }

    /**
     * 标记绘图范围
     *
     * @param pts
     * @param factors
     */
    void makingShowArea(List<LatLng> pts, ConvertFactors factors) {
        if (pts == null || pts.size() <= 0) {
            return;
        }
        if (factors.minLatitude == 0) {
            // 如果没有值，将第一项的值赋予它
            factors.minLatitude = pts.get(0).latitude;
            factors.maxLatitude = pts.get(0).latitude;
            factors.minLongitude = pts.get(0).longitude;
            factors.maxLongitude = pts.get(0).longitude;
        }
        for (LatLng pt : pts) {
            if (pt.latitude < factors.minLatitude) {
                factors.minLatitude = pt.latitude;
            } else if (pt.latitude > factors.maxLatitude) {
                factors.maxLatitude = pt.latitude;
            }
            if (pt.longitude < factors.minLongitude) {
                factors.minLongitude = pt.longitude;
            } else if (pt.longitude > factors.maxLongitude) {
                factors.maxLongitude = pt.longitude;
            }
        }
    }

    /**
     * 计算绘图参数
     *
     * @param factors
     */
    private void calcCoordinateFactorByCity(ConvertFactors factors, int width,
                                            int height) {
        // 计算Y跨度
        double disLatitude = factors.maxLatitude - factors.minLatitude;
        // 计算X跨度
        double disLongitude = factors.maxLongitude - factors.minLongitude;
        factors.xFactor = ROAD_GRAPHIC_WIDTH_NOINTERVAL / disLongitude;
        factors.yFactor = ROAD_GRAPHIC_WIDTH_NOINTERVAL / disLatitude;
        // 为了和IOS处理结果一样，需要对数据的小数位数进行处理
        factors.xFactor = Math.round(factors.xFactor * 1e11) / 1e11;
        factors.yFactor = Math.round(factors.yFactor * 1e11) / 1e11;
        // 获取缩放比例
        factors.factor = factors.xFactor < factors.yFactor ? factors.xFactor
                : factors.yFactor;
        // 获取图片的实际占用大小
        double actualWidth = disLongitude / factors.factor;
        double actualHei = disLatitude / factors.factor;
        // 确定起始坐标
        factors.showRect = new RectF((float) (width - actualWidth) / 2,
                (float) (height - actualHei) / 2,
                (float) (width + actualWidth) / 2,
                (float) (height + actualHei) / 2);

    }

    /**
     * 将数据列表中的数据转入绘图对象中
     *
     * @param froad
     * @param positiveDrawInfo
     */
    private void getConvertCoordsByCity(List<Segment> froad,
                                        DrawInfo positiveDrawInfo, ConvertFactors factors) {
        try {
            DrawInfo.Flag flag = new DrawInfo.Flag(true);
            for (int i = 0; i < froad.size(); i++) {
                Segment segment = froad.get(i);
                getConvertCoordsByCity(segment, positiveDrawInfo, factors, flag);
            }
        } catch (Exception e) {
        }
    }

    /**
     * 单个数据转为绘图数据
     *
     * @param segment
     * @param positiveDrawInfo
     * @param factors
     * @param flag
     */
    private void getConvertCoordsByCity(Segment segment,
                                        DrawInfo positiveDrawInfo, ConvertFactors factors, DrawInfo.Flag flag) {
        DrawInfo.DrawInfoUnit item;
        int ptsLen = segment.pts.size();
        for (int j = 0; j < ptsLen; j++) {
            LatLng p = segment.pts.get(j);
            item = new DrawInfo.DrawInfoUnit();
            if (j == 0 && ptsLen > 1 && flag.bFirst == false) {
                continue;
            }
            if (j == 0 && flag.bFirst) {
                // 第一个点
                item.sectionName = segment.getStartname();
                flag.bFirst = false;
            } else if (j == ptsLen - 1 && !flag.bFirst) {
                item.sectionName = segment.getEndname();
            }
            item.x = (float) ((p.longitude - factors.minLongitude)
                    * factors.factor + ROAD_GRAPHIC_INTERVAL);
            int nInterval = 0;
            if (factors.xFactor > factors.factor) {
                nInterval = (int) ((ROAD_GRAPHIC_WIDTH_NOINTERVAL - (factors.maxLongitude - factors.minLongitude)
                        * factors.factor) / 2);
                item.x += nInterval;
            }
            item.y = (float) ((p.latitude - factors.minLatitude)
                    * factors.factor + ROAD_GRAPHIC_INTERVAL);
            item.y = ROAD_GRAPHIC_WIDTH - item.y;
            if (factors.yFactor > factors.factor) {
                nInterval = (int) ((ROAD_GRAPHIC_WIDTH_NOINTERVAL - (factors.maxLatitude - factors.minLatitude)
                        * factors.factor) / 2);
                item.y -= nInterval;
            }
            positiveDrawInfo.arrDrawInfo.add(item);
        }
    }

    void addTrafficSegement(DrawInfo drawInfo, List<Vetrux> vectors,
                            List<TrafficSegment> trafficSegments, boolean bPositive) {
        if (drawInfo == null || drawInfo.arrDrawInfo == null
                || drawInfo.arrDrawInfo.size() == 0) {
            return;
        }
        String startName = "";
        String endName = "";
        String nRoadCondition = "";
        int listSize = drawInfo.arrDrawInfo.size();
        for (int i = 0; i < listSize; i++) {
            DrawInfo.DrawInfoUnit item = drawInfo.arrDrawInfo.get(i);
            if (i == 0) {
                // 添加节点
                vectors.add(new Vetrux((int) item.x, (int) item.y));
                startName = item.sectionName;
            } else {
                if (i <= drawInfo.arrRoadCondition.size()) {
                    nRoadCondition = drawInfo.arrRoadCondition.get(i - 1);
                } else {
                    nRoadCondition = "0";
                }
                endName = item.sectionName;
                // 添加节点
                vectors.add(new Vetrux((int) item.x, (int) item.y));
                add_traffic_segment(trafficSegments, vectors.size() - 1,
                        nRoadCondition, nRoadCondition, nRoadCondition,
                        startName, endName);
                //
                startName = endName;
            }
        }
    }

    static void add_traffic_segment(List<TrafficSegment> list,
                                    int vertex_count, String traffic_status, String up_traffic_status,
                                    String down_traffic_status, String startText, String endText) {
        TrafficSegment ts = new TrafficSegment();
        ts.vertex_count = vertex_count;
        ts.traffic_status = traffic_status;
        ts.up_traffic_status = up_traffic_status;
        ts.down_traffic_status = down_traffic_status;
        ts.startText = isEmpty(startText) ? "" : startText;
        ts.endText = isEmpty(endText) ? "" : endText;
        list.add(ts);
    }

    /**
     * 数据整理，去重
     *
     * @param array
     * @param type
     */
    private void rebuild_traffic_segment(List<TrafficSegment> array,
                                         TrafficGraphic.segment_outline_type_e type) {
        if (array == null || array.isEmpty()) {
            return;
        }
        List<TrafficSegment> cache = new ArrayList<TrafficSegment>();
        int nCount = array.size();
        TrafficSegment last = array.get(0);
        TrafficSegment current;
        int i = 1;
        for (; i < nCount; i++) {
            String curStatus = "0";
            String lastStatus = "0";
            current = array.get(i);
            if (type == TrafficGraphic.segment_outline_type_e.up_segment_outline) {
                curStatus = current.up_traffic_status;
                lastStatus = last.up_traffic_status;
            } else if (type == TrafficGraphic.segment_outline_type_e.down_segment_outline) {
                curStatus = current.down_traffic_status;
                lastStatus = last.down_traffic_status;
            } else if (type == TrafficGraphic.segment_outline_type_e.total_segment_outline) {
                curStatus = current.traffic_status;
                lastStatus = last.traffic_status;
            }
            // 如果当前点不需要标名字，且状态和上一点一致，则不需要绘制该点，合并两点信息
            if (curStatus.equals(lastStatus) && isEmpty(last.endText)
                    && isEmpty(current.startText)) {
                last.vertex_count = current.vertex_count;
                last.endText = current.endText;
            } else {
                cache.add(last);
                last = current;
            }
        }
        // 信息处理完成后，last未加入cache中，需要加入一次
        if (i == nCount) {
            cache.add(last);
        }
        array.clear();
        array.addAll(cache);
        cache = null;
    }

    void initScale(int w, int h) {
        w = Math.min(w, h);
        float deseniy = w * 1f / ROAD_GRAPHIC_WIDTH_DEF;
        ROAD_GRAPHIC_WIDTH_NOINTERVAL = ROAD_GRAPHIC_WIDTH_DEF
                - ROAD_GRAPHIC_INTERVAL_DEF * 2;
        ROAD_GRAPHIC_WIDTH = ROAD_GRAPHIC_WIDTH_DEF * deseniy;
        ROAD_GRAPHIC_INTERVAL = ROAD_GRAPHIC_INTERVAL_DEF * deseniy;
        // ROAD_GRAPHIC_LINE_WIDTH *= deseniy;
        ROAD_GRAPHIC_WIDTH_NOINTERVAL = ROAD_GRAPHIC_WIDTH
                - ROAD_GRAPHIC_INTERVAL * 2;
        TrafficGraphic.setGap(deseniy);
    }

    void linearSmooth3(List<Point> in) {
        List<Point> out = new ArrayList<Point>();
        if (in == null || in.size() < 3) return;
        int len = in.size();
        out.add(in.get(0));
        for (int i = 1; i < len - 1; i++) {
            Point per = in.get(i - 1);
            Point cur = in.get(i);
            Point next = in.get(i + 1);
            int x = (per.x + cur.x + next.x) / 3;
            int y = (per.y + cur.y + next.y) / 3;
            out.add(new Point(x, y));
        }
        out.add(in.get(len - 1));
        in.clear();
        in.addAll(out);
        out.clear();
    }
    private static  boolean isEmpty(String str){
        return str==null || "".equals(str) || "".equals(str.trim());
    }
}
